import { saveOrUpdateChatSessionBatch, saveOrUpdateSession, selectUserSessionByContactId } from "../db/ChatSessionUserModel";
import { saveMessageBatch, saveMessage } from "../db/ChatMessageModel";
import { updateContactNoReadCount } from "../db/UserSettingModel";
import { isEmpty } from "../util/common";
import { getStorageLocalSessionId, getStorageUserId } from "../plus/store/UserData";
import { messageType } from "../util/constants";

let ws = null;
let maxReConnectTimes = 0; //最大重连次数
let wsUrl;
let needReconnect = true;
let lock = false;

let wsListeners = {}; //储存各个页面的监听器

const initWs = (config) => {
    wsUrl = `ws://192.168.10.10:5051/ws?token=${config.token}`;
    needReconnect = true;
    maxReConnectTimes = 10;
    return creatWs();
}
 
const creatWs = () => {
    if(wsUrl == ''){
        return null;
    }
    if(ws != null && ws.readyState === 1){
        return ws;
    }
    ws = uni.connectSocket({
        url: wsUrl,
        header: {
            'content-type': 'application/json'
        },
        protocols: ['ws'],
        success: () => {
            console.log('\x1b[32m' + "建立webSocket中..."+ '\x1b[0m')
            console.log("ws = ", ws)
            return ws
        },
        fail: (e) => {
            console.log('\x1b[31m' + "建立webSocket失败!"+ '\x1b[0m', e)
            return null
        }
    })
    ws.onOpen((res) => {
        console.log('\x1b[32m' + "客户端连接正常！"+ '\x1b[0m')
        sendHeartBeat()
        maxReConnectTimes = 10
    })
    //从服务器接收到信息的回调函数
    ws.onMessage(async (e) => {
        console.log('\x1b[32m' + "收到服务器消息："+ '\x1b[0m', e.data)
        const message = JSON.parse(e.data);
        const messageType = message.messageType
        switch (messageType){
            case 0: //ws链接成功
                console.log('\x1b[32m' + "ws链接成功"+ '\x1b[0m')
                //保存会话信息
                if(!isEmpty(message.extendData.chatSessionUserList)){
                    await saveOrUpdateChatSessionBatch(message.extendData.chatSessionUserList)
                }
                //保存消息  
                if(!isEmpty(message.extendData.chatMessageList)){
                    await saveMessageBatch(message.extendData.chatMessageList)
                }
                if(!isEmpty(message.extendData.applyCount)){
                    //更新联系人未读数量
                    await updateContactNoReadCount({userId: getStorageUserId(), noReadCount: message.extendData.applyCount})
                }
                //返回消息
                notifyWsListener("reciveMessage", {messageType: message.messageType})
                break;
            case 2:
                if(message.sendUserId == getStorageUserId() && message.contactType == 1){
                    break;
                }
                const sessionInfo = {};
                if(message.extendData && typeof message.extendData === 'object'){
                    Object.assign(sessionInfo, message.extendData);
                }else{
                    Object.assign(sessionInfo, message);
                    if(message.contactType == 0 && messageType != 1){
                        sessionInfo.contactName = message.sendUserNickName
                    }
                    sessionInfo.lastReceiveTime = message.sendTime;
                }
                console.log("得到sessionInfo",sessionInfo)
                await saveMessage(message);
                await saveOrUpdateSession(getStorageLocalSessionId(), sessionInfo);
                const sessionUserInfo = await selectUserSessionByContactId(message.contactId);
                message.extendData = sessionUserInfo;
                //返回消息
                console.log('\x1b[32m' + "收到" + message.sendUserNickName + "的消息"+ '\x1b[0m', message)
                notifyWsListener("reciveNewMessage", message)
                break;
            case 13:
                //接受流消息
                console.log('\x1b[32m' + "收到流消息"+ '\x1b[0m', message)
                notifyWsListener("reciveNewMessage", message)
                break;

        }
    })
    //关闭ws
    ws.onClose(() => {
        console.log('关闭客户端连接重连')
        reconnect()
    })
    //产生错误
    ws.onError((e) => {
        console.log("连接失败准备重连", e)
        reconnect()
    })
    //重连
    const reconnect = () => {
        console.log("开始重连")
        if(!needReconnect){
            console.log("连接断开，无需重连")
            return null;
        }
        if(ws != null){
            ws.onClose(() => {
                console.log('关闭客户端连接重连')
                reconnect()
            })
        }
        if(lock){
            return null;
        }
        lock = true
        if(maxReConnectTimes > 0){
            console.log("准备重连，剩余重连次数" + maxReConnectTimes, new Date().getTime())
            maxReConnectTimes = maxReConnectTimes - 1
            setTimeout(() => {
                creatWs()
                lock = false
            }, 5000)
        }else {
            console.log("连接已超时, 关闭客户端连接")
            needReconnect = false
            ws.onClose({
                success: () => {
                console.log('WebSocket连接已关闭');
                }
            })
        }
    }
    //发心跳
    setInterval(() => {
        if(ws != null && ws.readyState === 1){
            sendHeartBeat()
        }
    }, 6000)
    //返回ws
    return ws
}
//关闭ws连接
const closeWs = () => {
    needReconnect = false
    ws.onClose({
        success: () => {
          console.log('WebSocket连接已关闭');
        }
    })
}
//发送心跳
const sendHeartBeat = () => {
    if(ws != null && ws.readyState === 1){
        let data = {
            messageType: messageType.HEART_BEAT,
            sendUserId: getStorageUserId(),
            content: "心跳包",
            sendTime: new Date().getTime()
        }
        ws.send({
            data: JSON.stringify(data),
            success: () => {
            },
            fail: (e) => {
                console.log('\x1b[31m' + "发送心跳包失败！"+ '\x1b[0m', e)
            }
        })
    }
}
//发送消息
const sendWsMessage = (data) => {
    if(ws != null && ws.readyState === 1){
        ws.send({
            data: JSON.stringify(data),
            success: () => {
                console.log('\x1b[32m' + "发送消息成功！"+ '\x1b[0m', data)
            },
            fail: (e) => {
                console.log('\x1b[31m' + "发送消息失败！"+ '\x1b[0m', e)
            }
        })
    }
}

//注册监听器
const addWsListener = (type, callback) => {
    if(isEmpty(wsListeners[type]) ){
       wsListeners[type] = []
    }
    wsListeners[type].push(callback)
}
//移除监听器
const removeWsListener = (type) => {
    if(isEmpty(wsListeners[type])){
        return null;
    }
    wsListeners[type] = []
}

//通知特定类型的监听器
const notifyWsListener = (type, data) => {
    let parseData = {}
    if(!isEmpty(data)){
        parseData = data
    }
    if(!isEmpty(wsListeners[type])){
        wsListeners[type].forEach(listener => listener(parseData));
    }
}

export {
    initWs,
    closeWs,
    addWsListener,
    notifyWsListener,
    sendWsMessage,
    removeWsListener
}

